<template>
  <div id="drag"></div>
</template>

<script setup>
import * as d3 from 'd3'
import { onMounted } from 'vue'
import graph from './json.js'

const { nodes, links } = graph

onMounted(() => {
  dragDemo()
})

function dragDemo() {
  const w = 660, h = 400
  const types = ['CITED_BY', 'suit', 'resolved']
  const color = d3.scaleOrdinal(d3.schemeBlues[3]);


  const simulation = d3.forceSimulation(nodes)
    .force('charge', d3.forceManyBody().distanceMax(900).strength(-1000))
    .force('collide', d3.forceCollide().radius(() => 30).iterations(1))
    .force('link', d3.forceLink(links).id(d => d.id).distance(160))
    .force('x', d3.forceX(w / 2))
    .force('y', d3.forceY(h / 2))

  let svg = d3.select('#drag').append('svg')
    .attr('class', 'svg')
    .attr('width', w)
    .attr('height', h)
    .attr("viewBox", [0, 0, w, h])
    .style('font', '12px sans-serif')

  svg.append('defs').selectAll('marker')
    .data(types)
    .join('marker')
    .attr("id", d => `arrow-${d}`)
    .attr("viewBox", "0 -5 10 10")
    .attr("refX", 42)
    .attr("refY", -3.8)
    .attr("markerWidth", 6)
    .attr("markerHeight", 6)
    .attr("orient", "auto")
    .append("path")
    .attr("fill", 'rgba(255,50,0,0.3)')
    .attr("d", "M0,-5L10,0L0,5");


  const link = svg.append('g')
    .attr("fill", "none")
    .attr("stroke-width", 1.5)
    .selectAll('path')
    .data(links)
    .join('path')
    .attr("stroke", d => color(d.type))
    .attr("marker-end", d => `url(${new URL(`#arrow-${d.type}`, location)})`)

  const node = svg.append('g')
    .attr("fill", "currentColor")
    .attr("stroke-linecap", "round")
    .attr("stroke-linejoin", "round")
    .selectAll("g")
    .data(nodes)
    .join("g")
    .attr('class', d => { console.log(d, 666) })
    .call(drag(simulation))

  node.append('circle')
    .attr('stroke', 'white')
    .attr('stroke-width', 1.5)
    .attr('r', d => {
      const size = [36, 30, 25, 22]
      return size[d.category] || 22
    })
    .attr('fill', (d, i) => {
      return color(d.category) || color(4)
    })
    .attr('stroke', 'rgba(120, 60, 60, 0.1)')
    .attr('stroke-width', 5)

  node.append('text')
    .text(d => d.name)
    .attr('text-anchor', 'middle')
    .attr('fill', 'rgba(120,33,44,0.8)')
    .attr('font-size', '12')

  simulation.on('tick', () => {
    link.attr("d", d => {
      const r = Math.hypot(d.target.x - d.source.x, d.target.y - d.source.y);
      return `M${d.source.x},${d.source.y} A${r},${r} 0 0,1 ${d.target.x},${d.target.y}`;
    });
    node.attr("transform", d => `translate(${d.x},${d.y})`);
  })

}

const drag = (simulation) => {
  function dragstarted(event, d) {
    if (!event.active) simulation.alphaTarget(0.3).restart();
    d.fx = d.x;
    d.fy = d.y;
  }

  function dragged(event, d) {
    d.fx = event.x;
    d.fy = event.y;
  }

  function dragended(event, d) {
    if (!event.active) simulation.alphaTarget(0);
    d.fx = null;
    d.fy = null;
  }
  return d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged)
    .on("end", dragended);
}







</script>
